package com.hsgene.product.service.impl;

import com.hsgene.common.ClientType;
import com.hsgene.common.DeleteFlagType;
import com.hsgene.common.UsedType;
import com.hsgene.common.util.code.CodeCreat;
import com.hsgene.common.util.exception.ValidationException;
import com.hsgene.common.util.result.ApiResult;
import com.hsgene.common.util.result.NullObject;
import com.hsgene.common.util.support.Pagination;
import com.hsgene.common.util.validation.FieldChecker;
import com.hsgene.dict.dto.SysDictDto;
import com.hsgene.generator.dto.GeneratorDto;
import com.hsgene.message.domain.PushInfo;
import com.hsgene.product.condition.PackageCondition;
import com.hsgene.product.constants.PeriodType;
import com.hsgene.product.constants.PolicyType;
import com.hsgene.product.constants.SortType;
import com.hsgene.product.domain.GeneticTestingPackage;
import com.hsgene.product.domain.GeneticTestingPackageAddtion;
import com.hsgene.product.domain.GeneticTestingProduct;
import com.hsgene.product.domain.GeneticTestingProductDetail;
import com.hsgene.product.dto.*;
import com.hsgene.product.dto.glaze.PackageDetailGlazDto;
import com.hsgene.product.dto.glaze.ProductDetailDto;
import com.hsgene.product.dto.peanut.*;
import com.hsgene.product.exception.ProductErrorCode;
import com.hsgene.product.persistence.*;
import com.hsgene.product.service.ElasticsearchService;
import com.hsgene.product.service.ProductService;
import com.hsgene.product.service.api.*;
import com.hsgene.sample.dto.GeneticTestingSampleDto;
import com.hsgene.supplier.dto.GeneticTestingAgencyDto;
import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.elasticsearch.rest.RestStatus;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import static org.apache.commons.lang.StringUtils.isNotEmpty;


/**
 * @desc:基因检测掏槽
 * @author: fuxiang
 * @date: 2018/9/18 16:06
 */
@Service
public class ProductServiceImpl implements ProductService {

    private final static Logger LOGGER = LogManager.getLogger(ProductServiceImpl.class);
    private static final String HP = "HP";
    private static final String HP_0001 = "HP0001";
    private static final int INT = 100;
    @Resource
    GeneticTestingPackageRepository packageRepository;
    @Resource
    GeneratorService generatorService;
    @Resource
    GeneticTestingProductPersistence productPersistence;
    @Resource
    GeneticTestingProductDetailRepository detailRepository;
    @Resource
    SampleService sampleService;
    @Resource
    DictService dictService;
    @Resource
    AgencyService agencyService;
    @Resource
    GeneticTestingPackageAddtionMapper addtionMapper;
    @Resource
    NotificationPushService notificationPushService;
    @Resource
    CommodityRepository commodityRepository;
    @Resource
    ElasticsearchService elasticsearchService;


    @Transactional(rollbackFor = Exception.class)
    @Override
    public ApiResult<GeneticTestingPackage>  addProduct(GeneticTestingPackage geneticTestingPackage) {

        // 套餐
        FieldChecker.checkEmpty(geneticTestingPackage, "geneticTestingPackage");
        //套餐字段校验
        geneticTestingPackage.check();
        //检测产品
        GeneticTestingProduct geneticTestingProduct = geneticTestingPackage.getGeneticTestingProduct();
        //产品字段校验
        geneticTestingProduct.check();
        ApiResult<GeneticTestingPackage> x = getGeneticTestingPackageApiResult(geneticTestingProduct);
        if (x != null) {
            return x;
        }
        //检查套餐名称是否存在
        GeneticTestingPackage geneticTestingPackage1 = packageRepository.getByPackageName(geneticTestingPackage.getPackageName());
        if (geneticTestingPackage1 != null) {
            return ApiResult.fail(ProductErrorCode.PACKAGE_ALREADY_EXISTS);
        }
        // 生成原始商品id
        ApiResult<GeneratorDto> generatorResult = generatorService.getGenerator("package", null);
        if (!generatorResult.isSucc()) {
            return ApiResult.fail(generatorResult.getError());
        }
        String id = generatorResult.getData().getSerialNumber();
        geneticTestingPackage.setId(id);
        geneticTestingPackage.setCategory("1");

        //package详情g构建
        List<GeneticTestingProductDetail> testingProductDetailList = getGeneticTestingProductDetails(geneticTestingPackage, geneticTestingProduct);
        //套餐对外机构code
        String code=packageRepository.selectOrderByCode();
        if(StringUtils.isEmpty(code)){
            geneticTestingPackage.setPackageCode(HP_0001);
        }else{
            String codeStr = CodeCreat.getCode(code,HP);
            geneticTestingPackage.setPackageCode(codeStr);
        }
        //插入套餐主表
        packageRepository.insertPackage(geneticTestingPackage);
        //产品信息
        ApiResult<GeneratorDto> generatorResultProduct = generatorService.getGenerator("product", null);
        if (!generatorResultProduct.isSucc()) {
            throw new ValidationException(generatorResultProduct.getCode() + ":" + generatorResultProduct.getDesc());
        }
        geneticTestingProduct.setId(generatorResultProduct.getData().getSerialNumber());
        geneticTestingProduct.setDeleteFlag(DeleteFlagType.NOT_DELETED.getCode());
        geneticTestingProduct.setPackageName(geneticTestingPackage.getPackageName());
        geneticTestingProduct.setPackageId(geneticTestingPackage.getId());
        productPersistence.insert(geneticTestingProduct);

        //产品详情信息
        for (GeneticTestingProductDetail detail : testingProductDetailList) {
            //机构字段校验
            detail.check();
            ApiResult<GeneratorDto> generatorResultDetail = generatorService.getGenerator("productDetail", null);
            if (!generatorResultDetail.isSucc()) {
                throw new ValidationException(generatorResultDetail.getCode() + ":" + generatorResultDetail.getDesc());
            }
            Date date = new Date();
            detail.setCreateDateTime(date);
            detail.setUpdateDateTime(date);
            detail.setId(generatorResultDetail.getData().getSerialNumber());
            detail.setDeleteFlag(DeleteFlagType.NOT_DELETED.getCode());
            detail.setProductId(geneticTestingProduct.getId());

        }
        detailRepository.insertMore(testingProductDetailList);
        //加到es中
        SetMealDto setMealDto = buildInfo(geneticTestingPackage);
        RestStatus status = elasticsearchService.addSetMealDto(setMealDto);
        if (status.getStatus() == RestStatus.CREATED.getStatus() || status.getStatus() == RestStatus.OK.getStatus()) {
            LOGGER.info("插入es成功",status.getStatus());
            return ApiResult.succ();
        } else {
            return ApiResult.fail(ProductErrorCode.ADD_SET_MEAL_TO_ELASTICSEARCH_IS_ERROR, status.name());
        }
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public ApiResult<GeneticTestingPackage> updateProduct(GeneticTestingPackage geneticTestingPackage) {
        // 套餐
        FieldChecker.checkEmpty(geneticTestingPackage, "geneticTestingPackage");
        //套餐字段校验
        geneticTestingPackage.check();
        //检测产品
        GeneticTestingProduct geneticTestingProduct = geneticTestingPackage.getGeneticTestingProduct();
        //产品字段校验
        ApiResult<GeneticTestingPackage> x = getGeneticTestingPackageApiResult(geneticTestingProduct);
        if (x != null) {
            return x;
        }
        geneticTestingProduct.check();
        //检查套餐名称是否存在
        GeneticTestingPackage geneticTestingPackage1 = packageRepository.getByPackageName(geneticTestingPackage.getPackageName());
        if (geneticTestingPackage1 != null && !geneticTestingPackage.getId().equals(geneticTestingPackage1.getId())) {
            return ApiResult.fail(ProductErrorCode.PACKAGE_ALREADY_EXISTS);
        }
        GeneticTestingPackage byPrimaryKey = packageRepository.selectByPrimaryKey(geneticTestingPackage.getId());
        //检验套餐是否被订单使用（下架并且未使用才能修改）
        GeneticTestingPackageAddtion addtion= addtionMapper.getByPackageId(geneticTestingPackage.getId());
        if(byPrimaryKey.getIsUsed()==1){
            return ApiResult.fail(ProductErrorCode.PACKAGE_HAS_BEEN_USED);
        }
        //检查是否上架
        if(addtion!=null&&addtion.getShelfStatus()==1){
            return ApiResult.fail(ProductErrorCode.ALREADY_ON_THE_SHELVES);
        }

        //套餐详情构建
        List<GeneticTestingProductDetail> testingProductDetailList = getGeneticTestingProductDetails(geneticTestingPackage, geneticTestingProduct);
        //修改套餐主表
        packageRepository.updateByPrimaryKey(geneticTestingPackage);
        if (StringUtils.isEmpty(geneticTestingProduct.getId())) {
            return ApiResult.fail(ProductErrorCode.PRIMARY_KEY_CANNOT_BE_EMPTY);
        }
        geneticTestingProduct.setDeleteFlag(0);
        geneticTestingProduct.setPackageName(geneticTestingPackage.getPackageName());
        geneticTestingProduct.setPackageId(geneticTestingPackage.getId());
        //修改product
        productPersistence.updateByPrimaryKey(geneticTestingProduct);
        //更新产品详情
        //删除被删掉的details
        if(geneticTestingPackage.getDeleteProductDetailIds()!=null&&geneticTestingPackage.getDeleteProductDetailIds().size()>0){
            detailRepository.deleteMore(geneticTestingPackage.getDeleteProductDetailIds());
        }
        //产品详情信息
        for (GeneticTestingProductDetail detail : testingProductDetailList) {
            //机构字段校验
            detail.check();
            detail.setDeleteFlag(DeleteFlagType.NOT_DELETED.getCode());
            detail.setUpdateDateTime( new Date());
            detail.setProductId(geneticTestingProduct.getId());
            detail.setCreateDateTime(detail.getUpdateDateTime());
            //存在的更新，不存在的添加
            if(isNotEmpty(detail.getId())){
                detailRepository.updateByPrimaryKey(detail);
            }else{
                ApiResult<GeneratorDto> generatorResultDetail = generatorService.getGenerator("productDetail", null);
                if (!generatorResultDetail.isSucc()) {
                    throw new ValidationException(generatorResultDetail.getCode() + ":" + generatorResultDetail.getDesc());
                }
                detail.setId(generatorResultDetail.getData().getSerialNumber());
                detailRepository.insert(detail);
            }
        }
        //es数据更新
        SetMealDto setMealDto = buildInfo(geneticTestingPackage);
        RestStatus status = elasticsearchService.updateSetMealDto(setMealDto);
        if (status.getStatus() == RestStatus.OK.getStatus()) {
            LOGGER.info("更新es成功",status.getStatus());
        } else {
            LOGGER.error("更新es失败",status.getStatus());
            return ApiResult.fail(ProductErrorCode.UPDATE_SET_MEAL_FROM_ELASTICSEARCH_IS_ERROR, status.name());
        }
        //推送消息给花生仁
        if(geneticTestingPackage.getIsToNotify()!=null&&geneticTestingPackage.getIsToNotify()==1){
            FieldChecker.checkEmpty(geneticTestingPackage, "推送内容不能为空");
            /*PushInfo pushInfo = getPushInfo(geneticTestingPackage);
            ApiResult<String> stringApiResult = notificationPushService.pushNotification(pushInfo, geneticTestingPackage.getUserId(), false);
            if(!stringApiResult.isSucc()){
                LOGGER.error("推送消息失败",stringApiResult.getDesc());
            }*/
        }
        return ApiResult.succ();
    }



    @Override
    public ApiResult<GeneticTestingPackage> getByPackageName(String packageName) {
        if (StringUtils.isEmpty(packageName)) {
            return ApiResult.fail(ProductErrorCode.PARAMETER_CANNOT_BE_EMPTY);
        }
        GeneticTestingPackage geneticTestingPackage = packageRepository.getByPackageName(packageName);
        return ApiResult.succ(geneticTestingPackage);
    }
    @Transactional(rollbackFor = Exception.class)
    @Override
    public ApiResult<NullObject> updateUsed(String packageId) {
        if(StringUtils.isEmpty(packageId)){
            return  ApiResult.fail(ProductErrorCode.PRIMARY_KEY_CANNOT_BE_EMPTY);
        }
        GeneticTestingPackage geneticTestingPackage = packageRepository.selectByPrimaryKey(packageId);
        if(geneticTestingPackage.getIsUsed()==UsedType.NO_USED.getCode()){
            packageRepository.updateUsed(packageId);
            //更改es
            SetMealDto setMealDto = new SetMealDto();
            setMealDto.setId(packageId);
            setMealDto.setIsUsed(UsedType.USED.getCode());
            elasticsearchService.updateSetMealDto(setMealDto);
            commodityRepository.updateUsed(packageId);
        }
        return ApiResult.succ();
    }

    @Override
    public ApiResult<Pagination<GeneticTestingPackageDto>> getList(PackageCondition condition) {
       /* int totalCount=packageRepository.getListCount(condition);
        Pagination<GeneticTestingPackageDto> pagination = Pagination.newInstance(condition.getLimitHelper(), totalCount);
        int rowNumber = (condition.getLimitHelper().getPage() - 1) * condition.getLimitHelper().getSize();
        if(totalCount>0){
            List<GeneticTestingPackageDto>  packageList=packageRepository.getList(condition);
            for (int i = 0, n = packageList.size(); i < n; i++) {
                GeneticTestingPackageDto geneticTestingPackageDto = packageList.get(i);
                geneticTestingPackageDto.setNumber(rowNumber + i + 1);
                GeneticTestingProduct byPackageId = productPersistence.getByPackageId(geneticTestingPackageDto.getId());
                geneticTestingPackageDto.setPolicyTypeDesc(PolicyType.getEnum(byPackageId.getPolicyType()).getDesc());
            }
            pagination.setResult(packageList);
        }else{
            pagination.setResult(new ArrayList<>());
        }
        return ApiResult.succ(pagination);*/


       //调用es接口
        QuerySetMealDto querySetMealDto = new QuerySetMealDto();
        BeanUtils.copyProperties(condition,querySetMealDto);
        querySetMealDto.setName(condition.getPackageName());
        querySetMealDto.setOrgs(condition.getAgencyName());
        querySetMealDto.setExcludeId(condition.getExcludeId());
        ApiResult<Pagination<SetMealDto>> search = elasticsearchService.search(querySetMealDto);
        if(!search.isSucc()){
            return ApiResult.fail(search.getError());
        }
        List<SetMealDto> result = search.getData().getResult();
        int rowNumber = (condition.getLimitHelper().getPage() - 1) * condition.getLimitHelper().getSize();
        List<GeneticTestingPackageDto> collect = IntStream.range(0, result.size()).mapToObj(i -> getGeneticTestingPackageDto(result.get(i), i,rowNumber)).collect(Collectors.toList());
        Pagination<GeneticTestingPackageDto> pagination = Pagination.newInstance(condition.getLimitHelper(), search.getData().getTotalCount());
        if( search.getData().getTotalCount()>0){
            pagination.setResult(collect);
        }else{
            pagination.setResult(new ArrayList<>());
        }
        return ApiResult.succ(pagination);
    }

    private GeneticTestingPackageDto getGeneticTestingPackageDto(SetMealDto c,int i,int rowNumber) {
        GeneticTestingPackageDto packageDto = new GeneticTestingPackageDto();
        BeanUtils.copyProperties(c, packageDto);
        GeneticTestingProduct byPackageId = productPersistence.getByPackageId(c.getId());
       // packageDto.setPolicyTypeDesc(PolicyType.getEnum(byPackageId.getPolicyType()).getDesc());
        packageDto.setPackageName(c.getName());
        packageDto.setCancerName(c.getCancers()[0].getName());
        packageDto.setDrugName(c.getMedicines()[0].getMedicineName());
        packageDto.setGeneticTestingAgencyName(getOrgCollect(c));
        packageDto.setDetectionPrice(new BigDecimal(Float.toString(c.getPrice())));
        packageDto.setNumber(rowNumber+i+1);
        if(c.getCommission()!=null){
            packageDto.setCommission(new BigDecimal(c.getCommission()));
        }
        return packageDto;
    }

    private String getOrgCollect(SetMealDto c) {
        return Arrays.stream(c.getOrgs()).map(Org::getName).collect(Collectors.joining(","));
    }

    @Override
    public ApiResult<Pagination<PackageList>> getListPeanut(PackageCondition condition) {

        /*int totalCount=packageRepository.getListCount(condition);
        Pagination<PackageList> pagination = Pagination.newInstance(condition.getLimitHelper(), totalCount);
        if(totalCount>0){
            List<GeneticTestingPackageDto>  packageListPage=packageRepository.getList(condition);
            List<PackageList> collect = packageListPage.stream().map(c -> {
                PackageList packageList = new PackageList();
                packageList.setId(c.getId());
                packageList.setCancerNames(c.getCancerName());
                packageList.setCommission(c.getCommission());
                packageList.setDetection(c.getDetection());
                packageList.setPrice(c.getDetectionPrice());
                packageList.setName(c.getPackageName());
                packageList.setOrg(c.getGeneticTestingAgencyName());
                packageList.setDiscription(c.getDescription());
                return packageList;
            }).collect(Collectors.toList());
            pagination.setResult(collect);
        }else{
            pagination.setResult(new ArrayList<>());
        }
        return ApiResult.succ(pagination);*/

        //es接口
        QuerySetMealDto querySetMealDto = queryInfo(condition);
        ApiResult<Pagination<SetMealDto>> search = elasticsearchService.search(querySetMealDto);
        if(!search.isSucc()){
            return ApiResult.fail(search.getError());
        }
        List<SetMealDto> result = search.getData().getResult();
        List<PackageList> collect = result.stream().map(c -> {
            PackageList packageDto = new PackageList();
            BeanUtils.copyProperties(c, packageDto);
            packageDto.setPrice(new BigDecimal(c.getPrice().toString()));
            packageDto.setCommission(new BigDecimal(c.getCommission().toString()));
            packageDto.setOrg(getOrgCollect(c));
            Cancer[] cancers = c.getCancers();
            String collect1 = Arrays.stream(cancers).map(Cancer::getName).collect(Collectors.joining(","));
            packageDto.setCancerNames(collect1);
            Medicine[] medicines = c.getMedicines();
            packageDto.setMedicineNames(Arrays.stream(medicines).map(Medicine::getMedicineName).collect(Collectors.joining(",")));
            packageDto.setCartStatus(String.valueOf(c.getCartStatus()));
            return packageDto;
        }).collect(Collectors.toList());
        Pagination<PackageList> pagination = Pagination.newInstance(condition.getLimitHelper(), search.getData().getTotalCount());
        if( search.getData().getTotalCount()>0){
            pagination.setResult(collect);
        }else{
            pagination.setResult(new ArrayList<>());
        }
        return ApiResult.succ(pagination);
    }

    private QuerySetMealDto queryInfo(PackageCondition condition) {
        QuerySetMealDto querySetMealDto = new QuerySetMealDto();
        BeanUtils.copyProperties(condition,querySetMealDto);
        querySetMealDto.setName(condition.getPackageName());
        querySetMealDto.setOrgs(condition.getAgencyName());
        querySetMealDto.setCondition(condition.getKeyword());
        querySetMealDto.setCancerIds(condition.getCancerId());
        querySetMealDto.setCancerNames(condition.getCancerName());
        querySetMealDto.setMedicineIds(condition.getGeneMedicine());
        return querySetMealDto;
    }

    @Override
    public ApiResult getByKeywordPage(PackageCondition condition) {
       /* int totalCount=packageRepository.getPeanueCount(condition);
        Pagination<GeneticTestingPackageKeywordPeanutDto> pagination = Pagination.newInstance(condition.getLimitHelper(), totalCount);
        if(totalCount>0){
            List<GeneticTestingPackageKeywordPeanutDto> keywordPeanutDtos= packageRepository.getByKeywordPage(condition);
            pagination.setResult(keywordPeanutDtos);
        }else{
            pagination.setResult(new ArrayList<>());
        }
        return ApiResult.succ(pagination);*/

        //调用es接口
        ApiResult<Pagination<SetMealDto>> search = getPaginationApiResult(condition);
        List<SetMealDto> result = search.getData().getResult();
        List<GeneticTestingPackageKeywordPeanutDto> collect3 = result.stream().map(c -> {
            GeneticTestingPackageKeywordPeanutDto peanutDto = new GeneticTestingPackageKeywordPeanutDto();
            BeanUtils.copyProperties(c, peanutDto);
            Medicine[] medicines = c.getMedicines();
            String collect = Arrays.stream(medicines).map(Medicine::getMedicineName).collect(Collectors.joining(","));
            peanutDto.setMedicineNamesStr(collect);
            Cancer[] cancers = c.getCancers();
            String collect1 = Arrays.stream(cancers).map(Cancer::getId).collect(Collectors.joining(","));
            peanutDto.setCancerIdsStr(collect1);
            String collect2 = Arrays.stream(cancers).map(Cancer::getName).collect(Collectors.joining(","));
            peanutDto.setCancerNamesStr(collect2);
            peanutDto.setPrice(new BigDecimal(Float.toString(c.getPrice())));
            peanutDto.setPackageName(c.getName());
            peanutDto.setCommission(new BigDecimal(c.getCommission()));
            peanutDto.setOrgs(getOrgCollect(c));
            return peanutDto;
        }).collect(Collectors.toList());
        Pagination<GeneticTestingPackageKeywordPeanutDto> pagination = Pagination.newInstance(condition.getLimitHelper(),  search.getData().getTotalCount());
        if( search.getData().getTotalCount()>0){
            pagination.setResult(collect3);
        }else{
            pagination.setResult(new ArrayList<>());
        }
        return ApiResult.succ(pagination);
    }

    @Override
    public ApiResult<Integer> getCountBySamplyId(String samplyId) {
       int a= detailRepository.getCountBySamplyId(samplyId);
        return ApiResult.succ(a);
    }



    @Override
    public ApiResult<List<GeneticTestingPackageKeywordPeanutDto>> getByKeyword(PackageCondition condition) {
        /*List<GeneticTestingPackageKeywordPeanutDto> keywordPeanutDtos= packageRepository.getByKeyword(condition.getKeyword());
        List<GeneticTestingPackageKeywordPeanutDto> collect = keywordPeanutDtos.stream().map(c -> {
            String[] split = StringUtils.split(c.getCancerNamesStr(), ",");
            c.setCancerNames(split);
            String[] split1 = StringUtils.split(c.getCancerIdsStr(), ",");
            c.setCancerIds(split1);
            String[] split2 = StringUtils.split(c.getMedicineNamesStr(), ",");
            c.setMedicineNames(split2);
            return c;
        }).collect(Collectors.toList());
        return ApiResult.succ(collect);*/
        //调用es
        ApiResult<Pagination<SetMealDto>> search = getPaginationApiResult(condition);
        List<SetMealDto> result =search.getData().getResult();
        List<GeneticTestingPackageKeywordPeanutDto> collect3 = result.stream().map(c -> {
            GeneticTestingPackageKeywordPeanutDto peanutDto = new GeneticTestingPackageKeywordPeanutDto();
            BeanUtils.copyProperties(c, peanutDto);
            Medicine[] medicines = c.getMedicines();
            peanutDto.setMedicineNames(Arrays.stream(medicines).map(Medicine::getMedicineName).toArray(String[]::new));
            Cancer[] cancers = c.getCancers();
            peanutDto.setCancerIds(Arrays.stream(cancers).map(Cancer::getId).toArray(String[]::new));
            peanutDto.setCancerNames( Arrays.stream(cancers).map(Cancer::getName).toArray(String[]::new));
            peanutDto.setPrice(new BigDecimal(Float.toString(c.getPrice())));
            peanutDto.setPackageName(c.getName());
            if(c.getCommission()!=null){
                peanutDto.setCommission(new BigDecimal(c.getCommission()));
            }
            peanutDto.setOrgs(getOrgCollect(c));
            return peanutDto;
        }).collect(Collectors.toList());
        return ApiResult.succ(collect3);
    }

    private ApiResult<Pagination<SetMealDto>> getPaginationApiResult(PackageCondition condition) {
        QuerySetMealDto querySetMealDto = new QuerySetMealDto();
        BeanUtils.copyProperties(condition, querySetMealDto);
        querySetMealDto.setCondition(condition.getKeyword());
        querySetMealDto.setPlatform(ClientType.PEANUT.getCode());
        return elasticsearchService.search(querySetMealDto);
    }

    @Override
    public ApiResult glazePackageDetail(String id) {
        ApiResult<GeneticTestingPackage> packageById = getPackageById(id,null);
        if(!packageById.isSucc()){
            return ApiResult.fail(packageById.getError());
        }
        GeneticTestingPackage packageByIdData = packageById.getData();
        GeneticTestingProduct geneticTestingProduct = packageByIdData.getGeneticTestingProduct();
        PackageDetailGlazDto packageDetailGlazDto = new PackageDetailGlazDto();
        packageDetailGlazDto.setProductId(id);
        packageDetailGlazDto.setProductName(packageByIdData.getPackageName());
        packageDetailGlazDto.setProductPrice(geneticTestingProduct.getDetectionPrice());
        packageDetailGlazDto.setCancerNames(geneticTestingProduct.getCancerName());
        packageDetailGlazDto.setMedicineName(geneticTestingProduct.getDrugName());
        packageDetailGlazDto.setTherapyType(geneticTestingProduct.getNature());
        packageDetailGlazDto.setGeneticPoints(geneticTestingProduct.getTargets());
        packageDetailGlazDto.setDesciption(geneticTestingProduct.getDescription());
        packageDetailGlazDto.setSignificance(geneticTestingProduct.getClinical());
        packageDetailGlazDto.setTherapyType(geneticTestingProduct.getNature());
        List<GeneticTestingProductDetail> testingProductDetailList = geneticTestingProduct.getTestingProductDetailList();
        List<ProductDetailDto> collect = testingProductDetailList.stream().map(c -> {
            ProductDetailDto productDetailDto = new ProductDetailDto();
            productDetailDto.setOrgName(c.getAgencyName());
            productDetailDto.setPeriod(c.getDetectionPeriod()+"个"+PeriodType.getEnum(c.getDetectionPeriodUnit()).getDesc());
            String[] split = StringUtils.split(c.getSampleTypeName(), ",");
            productDetailDto.setSpecimen(split);
            return productDetailDto;
        }).collect(Collectors.toList());
        packageDetailGlazDto.setOrgDetailList(collect);
        return ApiResult.succ(packageDetailGlazDto);
    }

    @Override
    public ApiResult<List<PackageDetilOrgsDto>> getArgsByPackageId(String id) {
        ApiResult<GeneticTestingPackage> packageById = getPackageById(id,null);
        GeneticTestingPackage packageByIdData = packageById.getData();
        List<GeneticTestingProductDetail> testingProductDetailList = packageByIdData.getGeneticTestingProduct().getTestingProductDetailList();
        List<PackageDetilOrgsDto> collect=new ArrayList<>();
        for(GeneticTestingProductDetail c:testingProductDetailList){
            PackageDetilOrgsDto packageDetilOrgsDto = new PackageDetilOrgsDto();
            packageDetilOrgsDto.setAgencyId(c.getAgencyId());
            ApiResult<GeneticTestingAgencyDto> organization = agencyService.getAgencyById(c.getAgencyId());
            if(!organization.isSucc()){
                return  ApiResult.fail(organization.getError());
            }
            GeneticTestingAgencyDto detectionOrganizationDto = organization.getData();
            packageDetilOrgsDto.setAgencyName(detectionOrganizationDto.getName());
            collect.add(packageDetilOrgsDto);
        }
        return ApiResult.succ(collect);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public ApiResult updateUsedMore(List<String> ids) {
        List<GeneticTestingPackage> geneticTestingPackage= packageRepository.getByPackageIds(ids);
        List<String> collect = geneticTestingPackage.stream()
                .filter(c -> c.getIsUsed().equals(UsedType.NO_USED.getCode()))
                .map(GeneticTestingPackage::getId)
                .collect(Collectors.toList());
        if(collect.size() > 0){
            packageRepository.updateUsedMore(collect);
            commodityRepository.updateUsedMore(collect);
            collect.forEach(c->{
                //更改es
                SetMealDto setMealDto = new SetMealDto();
                setMealDto.setId(c);
                setMealDto.setIsUsed(UsedType.USED.getCode());
                elasticsearchService.updateSetMealDto(setMealDto);
            });
        }
        return ApiResult.succ();
    }

    @Override
    public ApiResult<GeneticTestingPackage> getPackageById(String id,String costPermission) {
        if(StringUtils.isEmpty(id)){
            return  ApiResult.fail(ProductErrorCode.PRIMARY_KEY_CANNOT_BE_EMPTY);
        }
        GeneticTestingPackage geneticTestingPackage = packageRepository.selectByPrimaryKey(id);
        if(geneticTestingPackage==null){
            LOGGER.error("根据id查找套餐为空");
            return ApiResult.fail(ProductErrorCode.COMMODITY_NOT_EXISTED);
        }
        GeneticTestingProduct geneticTestingProduct= productPersistence.getByPackageId(id);
        geneticTestingProduct.setSortDesc(SortType.getEnum(geneticTestingProduct.getSort()).getDesc());
        List<GeneticTestingProductDetail> byProductId = detailRepository.getByProductId(geneticTestingProduct.getId());
        //产品详情对象封装
        for (GeneticTestingProductDetail detail : byProductId) {
            if (isNotEmpty(detail.getSampleType())) {
                String sampleType = detail.getSampleType();
                ApiResult<List<GeneticTestingSampleDto>> samplesByids = sampleService.getSamplesByids(sampleType);
                if(!samplesByids.isSucc()){
                    return ApiResult.fail(samplesByids.getError());
                }
                if (samplesByids.getData() != null) {
                       String sampleName = samplesByids.getData().stream().map(GeneticTestingSampleDto::getLabel).collect(Collectors.joining(","));
                        detail.setSampleTypeName(sampleName);
                }
            }
            if(isNotEmpty(detail.getAgencyId())){
                ApiResult<GeneticTestingAgencyDto> agencyById = agencyService.getAgencyById(detail.getAgencyId());
                if (agencyById.isSucc() && agencyById.getData() != null) {
                    detail.setAgencyName(agencyById.getData().getName());
                }
            }
            //检测平台
            if(isNotEmpty(detail.getDetectionPlatform())){
                //获取字典值
                String  collectFrom = getDictString(detail.getDetectionPlatform());
                detail.setDetectionPlatformDesc(collectFrom);
            }
            //检测方法
            if(isNotEmpty(detail.getDetectionMethod())){
                String dictString = getDictString(detail.getDetectionMethod());
                detail.setDetectionMethodDesc(dictString);
            }
            //检测周期
            if(isNotEmpty(detail.getDetectionPeriod())){
                //String dictString = getDictString(detail.getDetectionPeriod());
                detail.setDetectionPeriodDesc(detail.getDetectionPeriod()+"个"+PeriodType.getEnum(detail.getDetectionPeriodUnit()).getDesc());
            }
            if(StringUtils.isEmpty(costPermission)){
                detail.setCost(null);
            }

        }
        geneticTestingProduct.setTestingProductDetailList(byProductId);
        geneticTestingPackage.setGeneticTestingProduct(geneticTestingProduct);
        return ApiResult.succ(geneticTestingPackage);
    }

    private String getDictString(String form) {
        String collect=null;
            ApiResult<List<SysDictDto>> dictByIds = dictService.sysDicts(form);
            if (dictByIds.isSucc() && dictByIds.getData() != null) {
                 collect = dictByIds.getData().stream().map(SysDictDto::getValue).collect(Collectors.joining(","));
            }
        return collect;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public ApiResult<GeneticTestingPackage> deletePackageById(String id) {
        GeneticTestingPackageAddtion addtion= addtionMapper.getByPackageId(id);
        GeneticTestingProduct geneticTestingProduct= productPersistence.getByPackageId(id);
        //删除套餐需要检查当前套餐是否上架，如果是上架状态不能删除
        if(addtion!=null&&addtion.getShelfStatus()==1){
            return ApiResult.fail(ProductErrorCode.CAN_NOT_BE_DELETED);
        }
        packageRepository.deletePackageById(id);
        productPersistence.deleteProductByPackageId(id);
        detailRepository.deleteProductByProductId(geneticTestingProduct.getId());
        //es删除
        elasticsearchService.deleteSetMealDto(id);
        return ApiResult.succ();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public ApiResult<GeneticTestingPackageDto> deletePackageByIds(List<GeneticTestingPackageDto> condition) {
        if (condition == null || condition.isEmpty()) {
            return ApiResult.fail(ProductErrorCode.OBJECT_IS_EMPTY);
        }
        List<GeneticTestingPackageDto> dtoList=new ArrayList<>();
        for(GeneticTestingPackageDto packageDto:condition){
            GeneticTestingPackage geneticTestingPackage = packageRepository.selectByPrimaryKey(packageDto.getId());
            if(geneticTestingPackage!=null&&geneticTestingPackage.getIsUsed()== UsedType.USED.getCode()){
                dtoList.add(packageDto);
            }else{
                GeneticTestingProduct geneticTestingProduct= productPersistence.getByPackageId(packageDto.getId());
                packageRepository.deletePackageById(packageDto.getId());
                productPersistence.deleteProductByPackageId(packageDto.getId());
                detailRepository.deleteProductByProductId(geneticTestingProduct.getId());
                //es删除
                elasticsearchService.deleteSetMealDto(packageDto.getId());
            }
        }
        if(dtoList.size() > 0){
            StringBuilder stringBuilder=new StringBuilder();
            dtoList.stream().forEach(c-> stringBuilder.append(",").append(c.getNumber()));
            String stringBuilder1 = stringBuilder.deleteCharAt(0).toString();
            return new ApiResult(3008, "", "序号" + stringBuilder1 + "已被使用无法删除", null);
        }
        if(dtoList.size() == 0){
            return ApiResult.succ();
        }
        return  ApiResult.fail(ProductErrorCode.OPERATION_FAILED);
    }

    /**
     * 花生仁获取套餐详情
     * @param id 套餐id
     * @return
     */
    @Override
    public ApiResult<GeneticTestingPackagePeanutDto> peanutPackageDetail(String id) {
        ApiResult<GeneticTestingPackage> packageById = getPackageById(id,null);
        GeneticTestingPackage geneticTestingPackage = packageById.getData();
        GeneticTestingPackagePeanutDto packagePeanutDto = new GeneticTestingPackagePeanutDto();
        if(geneticTestingPackage!=null){
            packagePeanutDto.setId(geneticTestingPackage.getId());
            if(geneticTestingPackage.getGeneticTestingProduct()!=null){
                packagePeanutDto.setDetection(geneticTestingPackage.getGeneticTestingProduct().getDetection());
                packagePeanutDto.setCancerNames(geneticTestingPackage.getGeneticTestingProduct().getCancerName());
                packagePeanutDto.setMedicineName(geneticTestingPackage.getGeneticTestingProduct().getDrugName());
                packagePeanutDto.setName(geneticTestingPackage.getPackageName());
                packagePeanutDto.setOrgNames(geneticTestingPackage.getGeneticTestingAgencyName());
                packagePeanutDto.setPrice(geneticTestingPackage.getGeneticTestingProduct().getDetectionPrice());
                packagePeanutDto.setCommission(geneticTestingPackage.getGeneticTestingProduct().getCommission());
                packagePeanutDto.setNatureLabel(geneticTestingPackage.getGeneticTestingProduct().getNature());
                packagePeanutDto.setTargets(geneticTestingPackage.getGeneticTestingProduct().getTargets());
                packagePeanutDto.setGeneTestProductDetailModels(geneticTestingPackage.getGeneticTestingProduct().getTestingProductDetailList());
            }
        }
        return new ApiResult(200,"success","数据获取成功",packagePeanutDto);
    }

    /***
     * 花生仁查询套餐检测信息
     * @author jcl
     * @date 2019/1/8 9:51
     * @param packageId 套餐id
     * @param agencyId 机构id
     * @return
     */
    @Override
    public ApiResult packageTestingInfo(String packageId,String agencyId) {
        GeneticTestingProductDetailDto productDetailDto = detailRepository.packageTestingInfo(packageId,agencyId);
        if(productDetailDto!=null){
            //检测平台
            if(isNotEmpty(productDetailDto.getDetectionPlatform())){
                //获取字典值
                String  collectFrom = getDictString(productDetailDto.getDetectionPlatform());
                productDetailDto.setDetectionPlatformDesc(collectFrom);
            }
            //检测方法
            if(isNotEmpty(productDetailDto.getDetectionMethod())){
                String dictString = getDictString(productDetailDto.getDetectionMethod());
                productDetailDto.setDetectionMethodDesc(dictString);
            }
            //检测周期
            if(isNotEmpty(productDetailDto.getDetectionPeriod())){
                String dictString = getDictString(productDetailDto.getDetectionPeriod());
                productDetailDto.setDetectionPeriodDesc(dictString);
            }
            if (isNotEmpty(productDetailDto.getSampleType())) {
                ApiResult<List<GeneticTestingSampleDto>> samplesByids = sampleService.getSamplesByids(productDetailDto.getSampleType());
                if (samplesByids.isSucc() && samplesByids.getData() != null) {
                    String sampleName = samplesByids.getData().stream().map(c -> c.getLabel()).collect(Collectors.joining(","));
                    productDetailDto.setSampleTypeName(sampleName);
                }
            }
            if(isNotEmpty(productDetailDto.getAgencyId())){
                ApiResult<GeneticTestingAgencyDto> organization = agencyService.getAgencyById(productDetailDto.getAgencyId());
                if (organization.isSucc() && organization.getData() != null) {
                    productDetailDto.setConsignee(organization.getData().getConsignee());
                    productDetailDto.setAddress(organization.getData().getAddress());
                    productDetailDto.setPhone(organization.getData().getPhone());
                }
            }
        }
        return new ApiResult(200,"success","获取数据成功",productDetailDto);
    }



    @Override
    public ApiResult<List<GeneticTestingPackageDetilPeanutDto>> getDetailsByPackageId(String id) {
        ApiResult<GeneticTestingPackage> packageById = getPackageById(id,null);
        GeneticTestingPackage packageByIdData = packageById.getData();
        List<GeneticTestingProductDetail> testingProductDetailList = packageByIdData.getGeneticTestingProduct().getTestingProductDetailList();
        List<GeneticTestingPackageDetilPeanutDto> detilPeanutDtos=new ArrayList<>();
        for (GeneticTestingProductDetail c : testingProductDetailList) {
            ApiResult<GeneticTestingAgencyDto> organization = agencyService.getAgencyById(c.getAgencyId());
            if (!organization.isSucc()) {
                return ApiResult.fail(ProductErrorCode.FAILED_TO_GET_AGENCY_SERVICE);
            }
            GeneticTestingAgencyDto detectionOrganizationDto = organization.getData();
            GeneticTestingPackageDetilPeanutDto detilPeanutDto = new GeneticTestingPackageDetilPeanutDto();
            detilPeanutDto.setAddress(detectionOrganizationDto.getAddress());
            detilPeanutDto.setConsignee(detectionOrganizationDto.getConsignee());
            detilPeanutDto.setId(c.getAgencyId());
            detilPeanutDto.setMethod(c.getDetectionMethodDesc());
            detilPeanutDto.setOrgName(c.getAgencyName());
            detilPeanutDto.setPeriod(c.getDetectionPeriodDesc());
            detilPeanutDto.setPhone(detectionOrganizationDto.getPhone());
            detilPeanutDto.setPlatform(c.getDetectionPlatformDesc());
            detilPeanutDto.setSpecimen(c.getSampleTypeName());
            ApiResult<List<GeneticTestingSampleDto>> samplesByids = sampleService.getSamplesByids(c.getSampleType());
            if (samplesByids.isSucc() && samplesByids.getData() != null) {
                List<GeneticTestingSampleDto> sampleDtos = samplesByids.getData();
                List<SampleDto> sampleDtoList = sampleDtos.stream().map(r -> {
                    SampleDto sampleDto = new SampleDto();
                    sampleDto.setLabelKey(r.getLabelKey());
                    sampleDto.setLabelDescription(r.getLabelDescription());
                    sampleDto.setId(r.getId());
                    sampleDto.setLabel(r.getLabel());
                    return sampleDto;
                }).collect(Collectors.toList());
                detilPeanutDto.setSpecimenList(sampleDtoList);
            }
            detilPeanutDtos.add(detilPeanutDto);
        }
        return ApiResult.succ(detilPeanutDtos);
    }
    private SetMealDto buildInfo(GeneticTestingPackage geneticTestingPackage) {
        GeneticTestingProduct product = geneticTestingPackage.getGeneticTestingProduct();
        List<GeneticTestingProductDetail> testingProductDetailList = product.getTestingProductDetailList();
        SetMealDto setMealDto = new SetMealDto();

        setMealDto.setId(geneticTestingPackage.getId());
        setMealDto.setName(geneticTestingPackage.getPackageName());
        //药物
        Medicine medicine = new Medicine();
        medicine.setMedicineId(product.getId());
        medicine.setMedicineName(product.getDrugName());
        List<Medicine> medicines=new ArrayList<>();
        medicines.add(medicine);
        setMealDto.setMedicines(medicines.toArray(new Medicine[medicines.size()]));
        setMealDto.setTargets(product.getTargets());
        setMealDto.setDetection(product.getDetection());
        setMealDto.setClinical(product.getClinical());
        setMealDto.setPrice(product.getDetectionPrice().floatValue());
        setMealDto.setNature(product.getNature());
        if(product.getCommission()!=null){
            setMealDto.setCommission(product.getCommission().intValue());
        }
        setMealDto.setDescription(product.getDescription());
        //疾病
        Cancer cancer = new Cancer();
        cancer.setId(product.getCancerId());
        cancer.setName(product.getCancerName());
        List<Cancer> list=new ArrayList<>();
        list.add(cancer);
        setMealDto.setCancers(list.toArray(new Cancer[list.size()]));
        setMealDto.setNature(product.getNature());
        setMealDto.setDescription(product.getDescription());
        setMealDto.setOrgs(testingProductDetailList.stream().map(c -> new Org(c.getAgencyName())).toArray(Org[]::new));
        setMealDto.setUpdateDateTime(new Date());
        String collect1 = testingProductDetailList.stream().map(GeneticTestingProductDetail::getDetectionPeriod).collect(Collectors.joining(","));
        String collect = testingProductDetailList.stream().map(c -> c.getDetectionPeriod() + "个" + PeriodType.getEnum(c.getDetectionPeriodUnit()).getDesc()).collect(Collectors.joining(","));
        setMealDto.setTestPeriod(collect);
        setMealDto.setIntegration(0);
        setMealDto.setPolicyType(product.getPolicyType());
        setMealDto.setIsUsed(0);
        return setMealDto;
    }
    private ApiResult<GeneticTestingPackage> getGeneticTestingPackageApiResult(GeneticTestingProduct geneticTestingProduct) {
        /*if((geneticTestingProduct.getCommonGroundVal()+geneticTestingProduct.getCommonDoctorVal())!= INT){
            return ApiResult.fail(ProductErrorCode.WRONG_EXPERIENCE_VALUE);
        }
        if((geneticTestingProduct.getUrgentGroundVal()+geneticTestingProduct.getUrgentDoctorVal())!= INT){
            return ApiResult.fail(ProductErrorCode.URGENT_NEED_WRONG_EXPERIENCE_VALUE);
        }*/
        //机构校验
        List<GeneticTestingProductDetail> details = geneticTestingProduct.getTestingProductDetailList();
        long count = details.stream().map(GeneticTestingProductDetail::getAgencyId).distinct().count();
        if(count<details.size()){
            return ApiResult.fail(ProductErrorCode.INSTITUTIONAL_NAME_HAS_DUPLICATE_VALUES);
        }
        return null;
    }

    private PushInfo getPushInfo(GeneticTestingPackage geneticTestingPackage) {
        PushInfo pushInfo = new PushInfo();
        pushInfo.setTitle("套餐已修改");
        pushInfo.setContent(geneticTestingPackage.getContent());
        pushInfo.setBusinessKey("基因检测");
        pushInfo.setListType("2");
        pushInfo.setType("2");
        return pushInfo;
    }
    private List<GeneticTestingProductDetail> getGeneticTestingProductDetails(GeneticTestingPackage geneticTestingPackage, GeneticTestingProduct geneticTestingProduct) {
        List<GeneticTestingProductDetail> testingProductDetailList = geneticTestingProduct.getTestingProductDetailList();
        testingProductDetailList.forEach(c->{
            //机构
            ApiResult<GeneticTestingAgencyDto> agencyById = agencyService.getAgencyById(c.getAgencyId());
            if (agencyById.isSucc() && agencyById.getData() != null) {
                c.setAgencyName(agencyById.getData().getName());
            }
        });
        String collect = testingProductDetailList.stream().map(GeneticTestingProductDetail::getAgencyName).collect(Collectors.joining(","));
        geneticTestingPackage.setGeneticTestingAgencyName(collect);
        geneticTestingPackage.setDeleteFlag(DeleteFlagType.NOT_DELETED.getCode());
        geneticTestingPackage.setIsUsed(UsedType.NO_USED.getCode());
        return testingProductDetailList;
    }
}
